package com.tdcy.sys.controller;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.tdcy.framework.BaseController;
import com.tdcy.framework.exception.BaseException;
import com.tdcy.framework.util.RequestUtils;
import com.tdcy.framework.util.SessionUtils;
import com.tdcy.framework.util.StringUtils;
import com.tdcy.framework.util.VerifyCodeHelper;
import com.tdcy.framework.util.WebUtils;
import com.tdcy.sys.constant.AppConstants;
import com.tdcy.sys.dao.IUserKindDAO;
import com.tdcy.sys.dao.IUserRoleDAO;
import com.tdcy.sys.service.ILogManagerSvc;
import com.tdcy.sys.service.ILoginSvc;
import com.tdcy.sys.service.IUserSvc;
import com.tdcy.sys.service.bean.LoginCo;
import com.tdcy.sys.service.bean.LoginInfoBean;
import com.tdcy.sys.service.validator.LoginValidator;
import com.tdcy.sys.util.BusiContextExt;
import com.tdcy.sys.util.ParamUtils;
import com.tdcy.sys.util.SessionUtilExt;
import com.tdcy.sys.util.log.LogManager;
import com.tdcy.sys.util.log.LogTaskFactory;
import com.tdcy.sys.util.shiro.UsernamePasswordToken;

@Controller
@RequestMapping(value = "login")
public class LoginController extends BaseController {
	@Resource
	IUserKindDAO userKindDAO;

	@Resource
	ILoginSvc loginSvc;

	@Resource
	IUserSvc userSvc;

	@Resource
	ILogManagerSvc logSvc;

	@Resource
	IUserRoleDAO userrolesDAO;

	/**
	 * 登录验证
	 * 
	 * @param request
	 * @param userName
	 * @param userPassword
	 * @param vcode
	 * @return
	 * @throws IOException
	 */
	@ResponseBody
	@RequestMapping(value = "/checkLogin")
	public Object checkLogin(HttpServletRequest request, HttpServletResponse response, LoginCo loginCo) throws IOException {
		// 初步验证
		LoginValidator v = new LoginValidator();
		v.validateLogin(loginCo);

		// 验证码
		boolean flag = checkVerifyCode(request);
		if (!flag) {
			throw new BaseException("验证码错误或者已失效");
		}

		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(loginCo);
		token.setLoginCo(loginCo);

		LoginInfoBean loginInfo = new LoginInfoBean();
		token.setLoginInfo(loginInfo);

		boolean isrmemberName = "1".equals(loginCo.getIsRememberMe()) ? true : false;
		token.setRememberMe(isrmemberName);

		String error = null;
		try {
			subject.login(token);
		} catch (UnknownAccountException e) {
			error = "用户名/密码错误";
		} catch (IncorrectCredentialsException e) {
			error = "用户名/密码错误";
		} catch (AuthenticationException e) {
			error = e.getMessage();
		}
		if (error != null) {// 出错了，返回登录页面
			throw new BaseException(error);
		}

		// 记录登录日志
		LogManager.me().executeLog(LogTaskFactory.loginLog(loginInfo.getUserEO(), request.getRemoteAddr()));

		SessionUtils.setSession(request, AppConstants.SESSION_LOGIN_INFO, loginInfo);
		return WebUtils.createJSONSuccess("登录成功");
	}

	/**
	 * 退出
	 * 
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/logout")
	public Object logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
		LoginInfoBean loginInfo = BusiContextExt.getLoginInfo();
		if (loginInfo != null) {
			SessionUtilExt.removeLoginInfo(request);
			Subject subject = SecurityUtils.getSubject();
			if (subject.isAuthenticated()) {
				subject.logout();
			}

			LogManager.me().executeLog(LogTaskFactory.exitLog(loginInfo.getUserEO(), request.getRemoteAddr()));
		}

		return "redirect:/views/hlogin";
	}

	@ResponseBody
	@RequestMapping(value = "/verifycode")
	public Object verifycode(HttpServletRequest request, HttpServletResponse response) {
		VerifyCodeHelper helper = VerifyCodeHelper.getInstance();
		String verifyCode = helper.getVerifyCode();
		SessionUtilExt.setSession(request, "verifycode", verifyCode);
		return WebUtils.createJSONSuccess("获取成功", verifyCode);
	}

	@RequestMapping(value = "/verifycodeImage")
	public Object verifycodeImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
		VerifyCodeHelper helper = VerifyCodeHelper.getInstance();
		String verifyCode = helper.getVerifyCode();
		SessionUtilExt.setSession(request, "verifycode", verifyCode);
		
		ByteArrayOutputStream baos = helper.getVerfyImageOutStream(verifyCode);
		OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
		response.setContentType("image/jpeg");
		toClient.write(baos.toByteArray());
		toClient.flush();
		toClient.close();
		return null;
	}

	
	private boolean checkVerifyCode(HttpServletRequest request) {
		String checkcodeflag = ParamUtils.getParamValue("checkcode_flag");
		if ("1".equals(checkcodeflag)) {
			String inputValue = RequestUtils.getParameter(request, "verifycode");
			String saveValue = SessionUtilExt.getSessionValue(request, "verifycode");
			if (StringUtils.isEmpty(inputValue) || !inputValue.equalsIgnoreCase(saveValue)) {
				return false;
			} else {
				return true;
			}
		}

		return true;
	}

}
